home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / posixfile.py < prev    next >
Text File  |  2008-10-05  |  8KB  |  237 lines

  1. """Extended file operations available in POSIX.
  2.  
  3. f = posixfile.open(filename, [mode, [bufsize]])
  4.       will create a new posixfile object
  5.  
  6. f = posixfile.fileopen(fileobject)
  7.       will create a posixfile object from a builtin file object
  8.  
  9. f.file()
  10.       will return the original builtin file object
  11.  
  12. f.dup()
  13.       will return a new file object based on a new filedescriptor
  14.  
  15. f.dup2(fd)
  16.       will return a new file object based on the given filedescriptor
  17.  
  18. f.flags(mode)
  19.       will turn on the associated flag (merge)
  20.       mode can contain the following characters:
  21.  
  22.   (character representing a flag)
  23.       a       append only flag
  24.       c       close on exec flag
  25.       n       no delay flag
  26.       s       synchronization flag
  27.   (modifiers)
  28.       !       turn flags 'off' instead of default 'on'
  29.       =       copy flags 'as is' instead of default 'merge'
  30.       ?       return a string in which the characters represent the flags
  31.               that are set
  32.  
  33.       note: - the '!' and '=' modifiers are mutually exclusive.
  34.             - the '?' modifier will return the status of the flags after they
  35.               have been changed by other characters in the mode string
  36.  
  37. f.lock(mode [, len [, start [, whence]]])
  38.       will (un)lock a region
  39.       mode can contain the following characters:
  40.  
  41.   (character representing type of lock)
  42.       u       unlock
  43.       r       read lock
  44.       w       write lock
  45.   (modifiers)
  46.       |       wait until the lock can be granted
  47.       ?       return the first lock conflicting with the requested lock
  48.               or 'None' if there is no conflict. The lock returned is in the
  49.               format (mode, len, start, whence, pid) where mode is a
  50.               character representing the type of lock ('r' or 'w')
  51.  
  52.       note: - the '?' modifier prevents a region from being locked; it is
  53.               query only
  54. """
  55.  
  56.  
  57. class _posixfile_:
  58.     """File wrapper class that provides extra POSIX file routines."""
  59.  
  60.     states = ['open', 'closed']
  61.  
  62.     #
  63.     # Internal routines
  64.     #
  65.     def __repr__(self):
  66.         file = self._file_
  67.         return "<%s posixfile '%s', mode '%s' at %s>" % \
  68.                 (self.states[file.closed], file.name, file.mode, \
  69.                  hex(id(self))[2:])
  70.  
  71.     #
  72.     # Initialization routines
  73.     #
  74.     def open(self, name, mode='r', bufsize=-1):
  75.         import __builtin__
  76.         return self.fileopen(__builtin__.open(name, mode, bufsize))
  77.  
  78.     def fileopen(self, file):
  79.         import types
  80.         if repr(type(file)) != "<type 'file'>":
  81.             raise TypeError, 'posixfile.fileopen() arg must be file object'
  82.         self._file_  = file
  83.         # Copy basic file methods
  84.         for maybemethod in dir(file):
  85.             if not maybemethod.startswith('_'):
  86.                 attr = getattr(file, maybemethod)
  87.                 if isinstance(attr, types.BuiltinMethodType):
  88.                     setattr(self, maybemethod, attr)
  89.         return self
  90.  
  91.     #
  92.     # New methods
  93.     #
  94.     def file(self):
  95.         return self._file_
  96.  
  97.     def dup(self):
  98.         import posix
  99.  
  100.         if not hasattr(posix, 'fdopen'):
  101.             raise AttributeError, 'dup() method unavailable'
  102.  
  103.         return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
  104.  
  105.     def dup2(self, fd):
  106.         import posix
  107.  
  108.         if not hasattr(posix, 'fdopen'):
  109.             raise AttributeError, 'dup() method unavailable'
  110.  
  111.         posix.dup2(self._file_.fileno(), fd)
  112.         return posix.fdopen(fd, self._file_.mode)
  113.  
  114.     def flags(self, *which):
  115.         import fcntl, os
  116.  
  117.         if which:
  118.             if len(which) > 1:
  119.                 raise TypeError, 'Too many arguments'
  120.             which = which[0]
  121.         else: which = '?'
  122.  
  123.         l_flags = 0
  124.         if 'n' in which: l_flags = l_flags | os.O_NDELAY
  125.         if 'a' in which: l_flags = l_flags | os.O_APPEND
  126.         if 's' in which: l_flags = l_flags | os.O_SYNC
  127.  
  128.         file = self._file_
  129.  
  130.         if '=' not in which:
  131.             cur_fl = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
  132.             if '!' in which: l_flags = cur_fl & ~ l_flags
  133.             else: l_flags = cur_fl | l_flags
  134.  
  135.         l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFL, l_flags)
  136.  
  137.         if 'c' in which:
  138.             arg = ('!' not in which)    # 0 is don't, 1 is do close on exec
  139.             l_flags = fcntl.fcntl(file.fileno(), fcntl.F_SETFD, arg)
  140.  
  141.         if '?' in which:
  142.             which = ''                  # Return current flags
  143.             l_flags = fcntl.fcntl(file.fileno(), fcntl.F_GETFL, 0)
  144.             if os.O_APPEND & l_flags: which = which + 'a'
  145.             if fcntl.fcntl(file.fileno(), fcntl.F_GETFD, 0) & 1:
  146.                 which = which + 'c'
  147.             if os.O_NDELAY & l_flags: which = which + 'n'
  148.             if os.O_SYNC & l_flags: which = which + 's'
  149.             return which
  150.  
  151.     def lock(self, how, *args):
  152.         import struct, fcntl
  153.  
  154.         if 'w' in how: l_type = fcntl.F_WRLCK
  155.         elif 'r' in how: l_type = fcntl.F_RDLCK
  156.         elif 'u' in how: l_type = fcntl.F_UNLCK
  157.         else: raise TypeError, 'no type of lock specified'
  158.  
  159.         if '|' in how: cmd = fcntl.F_SETLKW
  160.         elif '?' in how: cmd = fcntl.F_GETLK
  161.         else: cmd = fcntl.F_SETLK
  162.  
  163.         l_whence = 0
  164.         l_start = 0
  165.         l_len = 0
  166.  
  167.         if len(args) == 1:
  168.             l_len = args[0]
  169.         elif len(args) == 2:
  170.             l_len, l_start = args
  171.         elif len(args) == 3:
  172.             l_len, l_start, l_whence = args
  173.         elif len(args) > 3:
  174.             raise TypeError, 'too many arguments'
  175.  
  176.         # Hack by davem@magnet.com to get locking to go on freebsd;
  177.         # additions for AIX by Vladimir.Marangozov@imag.fr
  178.         import sys, os
  179.         if sys.platform in ('netbsd1',
  180.                             'openbsd2',
  181.                             'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
  182.                             'freebsd6', 'freebsd7',
  183.                             'bsdos2', 'bsdos3', 'bsdos4'):
  184.             flock = struct.pack('lxxxxlxxxxlhh', \
  185.                   l_start, l_len, os.getpid(), l_type, l_whence)
  186.         elif sys.platform in ('aix3', 'aix4'):
  187.             flock = struct.pack('hhlllii', \
  188.                   l_type, l_whence, l_start, l_len, 0, 0, 0)
  189.         else:
  190.             flock = struct.pack('hhllhh', \
  191.                   l_type, l_whence, l_start, l_len, 0, 0)
  192.  
  193.         flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
  194.  
  195.         if '?' in how:
  196.             if sys.platform in ('netbsd1',
  197.                                 'openbsd2',
  198.                                 'freebsd2', 'freebsd3', 'freebsd4', 'freebsd5',
  199.                                 'bsdos2', 'bsdos3', 'bsdos4'):
  200.                 l_start, l_len, l_pid, l_type, l_whence = \
  201.                     struct.unpack('lxxxxlxxxxlhh', flock)
  202.             elif sys.platform in ('aix3', 'aix4'):
  203.                 l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
  204.                     struct.unpack('hhlllii', flock)
  205.             elif sys.platform in ('linux2', 'linux2-alpha', 'linux2-hppa',
  206.                                   'linux2-mips', 'linux2-sparc'):
  207.                 l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
  208.                     struct.unpack('hhllhh', flock)
  209.             else:
  210.                 l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
  211.                     struct.unpack('hhllhh', flock)
  212.  
  213.             if l_type != fcntl.F_UNLCK:
  214.                 if l_type == fcntl.F_RDLCK:
  215.                     return 'r', l_len, l_start, l_whence, l_pid
  216.                 else:
  217.                     return 'w', l_len, l_start, l_whence, l_pid
  218.  
  219. def open(name, mode='r', bufsize=-1):
  220.     """Public routine to open a file as a posixfile object."""
  221.     return _posixfile_().open(name, mode, bufsize)
  222.  
  223. def fileopen(file):
  224.     """Public routine to get a posixfile object from a Python file object."""
  225.     return _posixfile_().fileopen(file)
  226.  
  227. #
  228. # Constants
  229. #
  230. SEEK_SET = 0
  231. SEEK_CUR = 1
  232. SEEK_END = 2
  233.  
  234. #
  235. # End of posixfile.py
  236. #
  237.